体系的に学ぶ 安全なWebアプリケーションの作り方
情報
徳丸浩氏によるWebアプリケーションのセキュリティ定番本 通称『徳丸本』
実際に攻撃を仮想環境で試しながら学ぶことができる
2018/06/21に第2改訂版発売
1 Webアプリケーションの脆弱性とは
1.2 脆弱性があるとなぜ駄目なのか
経済的損失
法的な要求
利用者が回復不可能なダメージを受ける場合が多い
Webサイト利用者に嘘をつくことになる
攻撃インフラ(ボットネットワークなど)構築に荷担する
1.3 脆弱性が生まれる理由
バグによるもの
チェック機能の不足によるもの
1.5 本書の構成
1章: 導入
2章: 環境セットアップ
3章: 基礎知識
4章: 脆弱性パターンの原理から対策方法
本書の中心
5章: 代表的なセキュリティ機能
6章:文字コードとセキュリティ
7章: 脆弱性診断
tnagatomi.icon 初版は携帯電話に関する章だったのが第2版で置き換わってる
8章: Webアプリケーション以外の側面から安全性を高めるための施策の全体像
9章: 開発プロセス
2 実習環境のセットアップ
ブラウザはFirefox
著名ブラウザの中で唯一XSSフィルタが標準で実装されていない
tnagatomi.icon 第2版からMac環境も用意されてありがたや
3 Webセキュリティの基礎
3.1 HTTPとセッション管理
入力-確認-登録パターン
Referer
チェックすることでセキュリティに役立つ場合もあれば、改変、削除ができるので問題の原因になることもある
以下の場合はGETでなくPOST
データ更新など副作用を伴うリクエスト
秘密情報を送信する
送信するデータの総量が多い
hiddenパラメータなどブラウザ上では変更できない値も書き換え可能
hiddenパラメータのメリット
情報漏洩や第三者からの書き換えに対しては堅牢
利用者自身によって書き換えられては困る認証や認可に関する情報はセッション変数に保存、それ以外はまずhiddenパラメータに保存を検討
ステートレスなHTTP認証
Basic認証
一度成功するとブラウザが配下のディレクトリへのリクエストに自動的にAuthorizationヘッダを付与してくれる
認証と認可をしっかり区別する
認証は本人であることを確認すること
認可は認証済みの利用者に権限を与えること
セッション管理
クッキー
ブラウザに名前=変数の組を覚えさせる
アプリケーションデータの保持にはあまり用いられない
セッションID管理機構は自作せず開発ツールの提供するものを利用する
認証後にセッションIDを変更する
クッキーの属性
Domain属性は原則として設定しない
SecureはHTTPS通信に関わる
HttpOnlyはクロスサイト・スクリプティングと関係。悪影響は通常ないのでつけるとよい。
3.2 受動的攻撃と同一生成元ポリシー
能動的攻撃
受動的攻撃
単純な受動的攻撃
正規サイトを悪用する受動的攻撃
攻撃側にとってメリットが大きい
サイトをまたがった受動的攻撃
サンドボックス
同一オリジンである条件
URLのホスト(FQDN)が一致している
スキームが一致している
ポート番号が一致している
3.3 CORS (Cross-Origin Resource Sharing)
サイトを超えてデータをやり取りできる仕様
リクエストの種類
シンプルなリクエスト
プリフライトリクエスト
認証情報を含むリクエスト
リクエストの種類に応じて許可するレスポンスヘッダを返す必要がある
4 Webアプリケーションの機能別に見るセキュリティバグ
4.1 Webアプリケーションの機能と脆弱性の対応
出力に起因する脆弱性はすべてインジェクション系
データの終端を示すマークを混入し、その後の文字列の構造を変化させる
Webアプリの脆弱性は機能との関連性が強い
4.2 入力処理とセキュリティ
バイナリセーフ
入力値が典型的には値ゼロのバイトであっても正しく扱えること
入力値検証
あくまで保険的対策
最大文字数はすべてのパラメータについて定義すべき
PHPではfilter_input関数で入力値検証
正規表現
全体一致は\Aと\zで示す
\d、\wは全角文字にもマッチするため[a-zA-Z0-9_]と明示するほうが安全
4.3 表示処理に伴う問題
クロスサイト・スクリプティング (XSS)
基本編
攻撃手法
クッキー値の読み出し
JavaScriptによる攻撃
画面の書き換え
JavaScript不使用
XSS攻撃は常にJavaScriptを使うとは限らない
攻撃用JavaScriptがどこにあるかによる分類
反射型XSS
持続型XSS
XSSの必要最小限の対策
要素内容については < と & をエスケープ
属性値についてはダブルクォートで囲って < と " と & をエスケープする
PHPではhtmlspecialchars関数を使う
共通対策
HTTPレスポンスに文字エンコーディングを明示する
保険的対策
X-XSS-Protection レスポンスヘッダを使用する
XSSフィルタを上書きして有効化
入力値を検証する
クッキーにHttpOnly属性を付与する
TRACEメソッドを無効化する
発展編
JavaScriptの動的生成の対策
カスタムデータ属性
インラインJSONP
4.4 SQL呼び出しに伴う脆弱性
SQLインジェクション
エラーメッセージには内部的なエラー内容は含ませない
対策
プレースホルダによりSQL文を組み立てる
静的・動的の2種類があり、静的の方が優れている
保険的対策
詳細なエラーメッセージの抑止
入力値の妥当性検証
データベースの権限設定
4.5 「重要な処理」の際に混入する脆弱性
CSRF
対策
CSRF対策の必要なページを区別する
正規利用者の意図したリクエストを区別できるよう実装する
秘密情報(トークン)の埋め込み
推奨される方法
トークンを受け付けるリクエストはPOSTメソッドにする
パスワード再入力
Refererのチェック
保険的対策
処理内容の通知メールを送信
クリックジャッキング
対策
frameおよびiframeでの参照を制限するX-Frame-Optionsを指定する
4.6 セッション管理の不備
セッションハイジャック
対策
認証ごにセッションIDを変更する
セッションIDの変更ができない場合はトークンにより対策する
4.7 リダイレクト処理にまつわる脆弱性
オープンリダイレクト脆弱性
HTTPヘッダ・インジェクション脆弱性
対策
リダイレクト処理にはできるだけ専用のAPIを使用する
以下のいずれかを実施
リダイレクト先は固定にする(推奨)
外部から指定するリダイレクト先のURLは、必ず文字種とドメイン名をチェックする
4.8 クッキー出力にまつわる脆弱性
対策
クッキーにセキュア属性をつける
4.9 メール送信の問題
対策
メール送信には専用のライブラリを使用する
その上で、以下のいずれかを実施
外部からのパラメータをメールヘッダに含ませないようにする
外部からのパラメータには改行を含まないようにメール送信時にチェックする
保険的対策
メールアドレスのチェック
件名のチェック
4.10 ファイルアクセスにまつわる問題
ディレクトリトラバーサル脆弱性
対策
外部からファイル名を指定できる仕様を避ける
ファイル名にディレクトリ名が含まれないようにする
ファイル名を英数字に限定する
4.11 OSコマンド呼び出しの際に発生する脆弱性
OSコマンド・インジェクション
対策
OSコマンド呼び出しを使わない実装方法を選択する
シェル呼び出し機能のある関数の利用を避ける
外部から入力された文字列をコマンドラインのパラメータに渡さない
OSコマンドに渡すパラメータを安全な関数によりエスケープする
保険的対策
パラメータの検証
アプリケーションの稼働する権限を最小限にする
WebサーバーのOSやミドルウェアのパッチ適用
4.12 ファイルアップロードにまつわる問題
5 代表的なセキュリティ機能
5.1 認証
オフラインブルートフォース攻撃
tnagatomi.icon GPUを活用したオフラインブルートフォース攻撃の高速化なんてあるのか。恐ろしい。
レインボーテーブル
tnagatomi.icon 10文字程度のSHA-1用テーブルが売られている。恐ろしい。
パスワードのマスク表示
tnagatomi.icon マスク表示のせいで簡単なパスワードを好むようになるから一概にマスク表示するといいとは言えない。なるほど。
IDとパスワードを二段階で入力するサイトの増加
tnagatomi.icon これも負担が増えることで安易なパスワードをつける傾向になることからと考えられるとのこと
7 脆弱性診断入門
tnagatomi.icon サンプルアプリで会員登録しようとしたら「只今サイトが大変混雑しています。もうしばらく経ってからアクセスしてください」って出て登録できなかったので読んだだけ。
感想
HTTPのリクエストとレスポンスを人間の会話に例えて図入りで表現されていて解りやすい
PHPによるサンプルコードがあるのでセキュリティだけではなくPHPの勉強にもなる
第2版
例として使用されているPHP以外の言語が初版と変わらないままで惜しいと思った
Perl…